package com.itcam.cloud.config;

import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient;
import org.springframework.cloud.loadbalancer.core.RandomLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.web.client.RestTemplate;

@Configuration
@LoadBalancerClient(
        //下面的value值大小写一定要和consul里面的名字一样，必须一样
        value = "cloud-payment-service",configuration = RestTemplateConfig.class)
public class RestTemplateConfig {
    /**
     * 配置并创建一个 RestTemplate 实例，用于进行 HTTP 请求。
     * 该 RestTemplate 实例被标记为 @LoadBalanced，意味着它将支持客户端负载均衡。
     * 在使用该 RestTemplate 进行服务调用时，Spring Cloud 会自动处理服务实例的选择和负载均衡。
     *
     * @return 一个带有负载均衡功能的 RestTemplate 实例。
     */
    @Bean
    @LoadBalanced //使用@LoadBalanced注解赋予RestTemplate负载均衡的能力
    public RestTemplate restTemplate() {
        // 创建并返回一个新的 RestTemplate 实例
        return new RestTemplate();
    }

    /**
     * 配置并创建一个随机负载均衡器实例。
     * 该方法通过 Spring 的 @Bean 注解将返回的负载均衡器注册到 Spring 容器中。
     * 使用随机负载均衡策略，从服务实例列表中随机选择一个服务实例进行请求。
     *
     * @param environment  Spring 的环境配置对象，用于获取配置属性。
     * @param loadBalancerClientFactory 负载均衡客户端工厂，用于获取服务实例列表供应商。
     * @return 一个使用随机负载均衡策略的 ReactorLoadBalancer 实例。
     */
    @Bean
    ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
                                                            LoadBalancerClientFactory loadBalancerClientFactory) {
        // 从环境配置中获取服务名称
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);

        // 创建并返回一个随机负载均衡器实例
        return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
    }


}